package com.roc.web.action.profit;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.roc.newPage.IPageService;
import com.roc.page.BaseSearchCondition;
import com.roc.page.PaginationBaseAction;
import com.roc.pojo.Operators;
import com.roc.pojo.ProfitDetail;
import com.roc.service.IExcelExportService;
import com.roc.service.ServiceException;
import com.roc.service.operator.IPowerInfoService;
import com.roc.service.profit.IProfitService;
import com.roc.util.AmtUtil;
import com.roc.util.Constance;
import com.roc.util.Utils;
import com.roc.util.constant.Constant;
import com.roc.util.constant.Role;
@Controller
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@Namespace("/ysbprofit")
public class YsbProfitDetailQueryAction  extends PaginationBaseAction{

	private Logger logger=LogManager.getLogger(YsbProfitDetailQueryAction.class);
	private YsbProfitDetailQuerySearchCondition searchCondition;
	@Autowired
	IPageService pagenitionService;
	@Autowired
	private IProfitService profitService;
	@Autowired
	IPowerInfoService powerInfoService;
	@Autowired
	private IExcelExportService excelExportService;
	
	private InputStream excelFile;
	private String excelName;
	
	private String accountNo;
	
	private String result;
	
	private Map<String,BigDecimal>  profitRuleMap;
	
	
	@Action(value="getOpertorsByAccountNo")
	public void getOpertorsByAccountNo()
	{
		HttpServletResponse response=ServletActionContext.getResponse();
		response.setContentType("text/json;charset=UTF-8");
		try {
			Operators operators=profitService.getOpertorsByAccountNo(accountNo);
			Map<String, Object> mapList=new HashMap<String,Object>();
			String code="fail";
			Object message="代理商账号对应的代理商不存在";
			if(operators!=null)
			{
				code="success";
				message=operators.getId();
			}
			 mapList.put("code",code);
			 mapList.put("message",message);
			result=JSONObject.fromObject(mapList).toString();
			response.getWriter().print(result);
		} catch (Exception e) {
			logger.info(e.getMessage(),e);
		} 
	}
	

	@Action(value = "initProfitDetail", results = {@Result(name = "success", location = "/pages/profit/ysbProfitDetail.jsp") })
	public String initProfitDirectlyAgentSum() throws ServiceException{
		init();
		return SUCCESS;
	}
	
	
	private void init()throws ServiceException{
		Operators logingOperators=(Operators)getSession().getAttribute(Constant.SESSION_LOGIN_MERCHANT);
		Map map= new HashMap();
		try{
			//根据登录人角色显示不同代理商
			Map<String, String> mapReal=powerInfoService.queryRealIdByOpId(logingOperators.getSuperiorId(),logingOperators.getRoleType(),logingOperators.getId(),logingOperators.getOrgCode());
            String superRole= mapReal.get("superRole");
            String opRealId =mapReal.get("opRealId");

            if(Role.AGENT.getCode().equals(superRole)||Role.O_MANAGER.getCode().equals(superRole)||Role.SYSTEM.getCode().equals(superRole)){
				 map =  profitService.getYsbOpertorsIdsTreeById(Long.parseLong(opRealId),superRole);
			}
			getRequest().setAttribute("agnetList",map);
		}
		catch (Exception e) {
			logger.error(e.getMessage(), e);
			addActionError(e.getMessage());
		}
	}
	
	@Action(value = "queryProfitDetail", results = { 
			@Result(name = "success", location = "/pages/profit/ysbProfitDetail.jsp"),
            @Result(name="error",location="/pages/profit/ysbProfitDetail.jsp"),
            @Result(name="login",location="/pages/profit/ysbProfitDetail.jsp") })

	public String queryProfitDetail() throws ServiceException{
		init();
		if(searchCondition==null){
			searchCondition=(YsbProfitDetailQuerySearchCondition)getSearchConditionFromSession();
			if(searchCondition==null){
				searchCondition=new YsbProfitDetailQuerySearchCondition();
			}
		}
		Operators operators=profitService.loadById(searchCondition.getId());
		 profitRuleMap =  profitService.queryProfitRule(operators.getAccountNo());
		try {
			int rows=pagenitionService.countSQL(searchCondition);
			Calendar c = Calendar.getInstance();//默认是当前日期 
			long start =c.getTimeInMillis();
			searchRsList=pagenitionService.findAllSQL(searchCondition, calcuStart(getCurrentPage()), Constance.PAGE_MAX_SIZE);
			c = Calendar.getInstance();
			long end =c.getTimeInMillis();
			long  totalTime = end -start;
			c.setTimeInMillis(totalTime);
			logger.info("-- 云商宝分润明细导出查询需要语句:"+searchCondition.getSearchHQL()+"\n用时= "+ (c.get(Calendar.HOUR_OF_DAY)-8)+":"+ c.get(Calendar.MINUTE)+":"+ c.get(Calendar.SECOND)+":"+ c.get(Calendar.MILLISECOND));
			//searchRsList=pagenitionService.findAllSQL(searchCondition, 0, 9999999);
			dealWithTheListSpecially(searchRsList);
			this.setTotalPage(this.calcuTotalPage(rows));
			getRequest().setAttribute(SEARCH_RS_LIST, searchRsList);
			getRequest().setAttribute(CURRENT_PAGE, this.getCurrentPage());
			getRequest().setAttribute(TOTAOL_PAGE, this.getTotalPage());
			setSearchToConditionSession(searchCondition);
		
		} catch (ServiceException e) {
			
			logger.error(e.getMessage(),e);
			addActionError("云商宝分润汇总查询失败");
			
		}
		return SUCCESS;
	}
	
	
	@Action(value="exportProfitDetail",results = {@Result(name="success",type="stream"
			,params = { "contentType", "application/vnd.ms-excel", "inputName",  
			            "excelFile","contentDisposition",  "attachment;filename=\"${excelName}\"",
			            "bufferSize", "1024*3" }),@Result(name="error",location="/pages/profit/profitDetail.jsp") }) 
	public String  exportProfitDetail() throws Exception{
		
				if(searchCondition==null){
					searchCondition=(YsbProfitDetailQuerySearchCondition)getSearchConditionFromSession();
					if(searchCondition==null){
						searchCondition=new YsbProfitDetailQuerySearchCondition();
					}
				}
				String temp =searchCondition.getBeginTime()+"至"+searchCondition.getEndTime()+"云商宝分润明细查询.xls";	
				if(-1!=searchCondition.getId()){
					Operators operators=profitService.loadById(searchCondition.getId());
					 profitRuleMap =  profitService.queryProfitRule(operators.getAccountNo());
					if(null !=operators){
						temp = operators.getRealName()+"--"+searchCondition.getBeginTime()+"至"+searchCondition.getEndTime()+"云商宝分润明细查询.xls";	
					}
				}
				excelName=new String(temp.getBytes(),"ISO8859-1");
				try {
					Calendar c = Calendar.getInstance();//默认是当前日期 
					long start =c.getTimeInMillis();
					searchRsList=pagenitionService.findAllSQL(searchCondition, 0, 9999999);
					c = Calendar.getInstance();
					long end =c.getTimeInMillis();
					long  totalTime = end -start;
					c.setTimeInMillis(totalTime);
					logger.info("-- 云商宝分润明细导出查询需要语句:"+searchCondition.getSearchHQL()+"\n用时= "+ (c.get(Calendar.HOUR_OF_DAY)-8)+":"+ c.get(Calendar.MINUTE)+":"+ c.get(Calendar.SECOND)+":"+ c.get(Calendar.MILLISECOND));
					
					dealWithTheList(searchRsList);
					String  reportName = "云商宝分润明细查询";//标题名字
					String[]  headArray=new String[]{"商户代码","商户名称","卡类型","交易类型","金额","分润","交易日期","交易卡号","系统参考号","终端号","结算日期"}; //表格列头
					
					HSSFWorkbook work=excelExportService.excelExport(reportName, headArray, searchRsList);

					 ByteArrayOutputStream output = new ByteArrayOutputStream();  
					         work.write(output);  
					   
					        byte[] ba = output.toByteArray();  
					         excelFile = new ByteArrayInputStream(ba);  
					         output.flush();  
					         output.close();  
					
		}catch (ServiceException e) {
			e.printStackTrace();
			logger.error(e.getMessage(),e);
			addActionError(e.getMessage());
			
		}
		
		return SUCCESS;
	}
	
	private void dealWithTheList(List<Object> list)throws Exception {
	List<Object> tempList=new ArrayList<Object>();
	if(list!=null&&list.size()>0){
		for (int i=0;i<list.size();i++){
			Object[] obj=(Object[]) list.get(i);
			Object[] prof=new Object[11];
			/*prof[0]=Constance.Null2EmptyTrim(obj[0]);
			prof[1]=Constance.Null2EmptyTrim(obj[1]);
			prof[2]=Constance.Null2EmptyTrim(obj[2]);
		
			String cardClass=Constance.Null2EmptyTrim(obj[3]);
			String prodCd= Constance.Null2EmptyTrim(obj[4]);
			double amt= Double.parseDouble(Constance.null2Amt(obj[5]));
			double feeffd= Double.parseDouble(Constance.null2Amt(obj[6]));//封顶值
			double merfee= Double.parseDouble(Constance.null2Amt(obj[7]));//封顶值
			
			double  profitSettleRate=0;
			if(merfee==feeffd){
				profitSettleRate=(Double) profitRuleMap.get("0199");
			}else{
				double  profitFee=0;
				if("消费".equals(cardClass)&&"借记卡".equals(prodCd)){
					profitFee=(Double) profitRuleMap.get("0100");
				}else if("消费".equals(cardClass)&&"贷记卡".equals(prodCd)){
					profitFee=(Double) profitRuleMap.get("0101");
				}else if("实时收款".equals(cardClass)&&"借记卡".equals(prodCd)){
					profitFee=(Double) profitRuleMap.get("0400");
				}else if("实时收款".equals(cardClass)&&"贷记卡".equals(prodCd)){
					profitFee=(Double) profitRuleMap.get("0401");
				}else{
					profitFee=(Double) profitRuleMap.get("0401");
				}
				  profitSettleRate =AmtUtil.round(AmtUtil.mul(amt, profitFee), 2);
			}
			prof[3]=cardClass;
			prof[4]=prodCd;
			prof[5]=amt;
			prof[6]=AmtUtil.sub(merfee, profitSettleRate);
			prof[7]=Constance.Null2EmptyTrim(obj[8]);
			prof[8]=Utils.dealCardNo(Constance.Null2EmptyTrim(obj[9]));
			prof[9]=Constance.Null2EmptyTrim(obj[10]);
			prof[10]=Constance.Null2EmptyTrim(obj[11]);*/
			//prof[0]=Constance.Null2EmptyTrim(obj[0]);
			prof[0]=Constance.Null2EmptyTrim(obj[1]);
			prof[1]=Constance.Null2EmptyTrim(obj[2]);
		
			String cardClass=Constance.Null2EmptyTrim(obj[3]);
			String prodCd= Constance.Null2EmptyTrim(obj[4]);
			BigDecimal amt= new BigDecimal(Constance.null2Amt(obj[5]));
			BigDecimal feeffd= new BigDecimal(Constance.null2Amt(obj[6]));//封顶值
			BigDecimal merfee= new BigDecimal(Constance.null2Amt(obj[7]));//封顶值
			BigDecimal restMerfee=getMerfee(amt,merfee,feeffd,cardClass,prodCd);
			prof[5]=restMerfee;
			prof[2]=cardClass;
			prof[3]=prodCd;
			prof[4]=amt;
			prof[6]=Constance.Null2EmptyTrim(obj[8]);
			prof[7]=Utils.dealCardNo(Constance.Null2EmptyTrim(obj[9]));
			prof[8]=Constance.Null2EmptyTrim(obj[10]);
			prof[9]=Constance.Null2EmptyTrim(obj[11]);
			prof[10]=Constance.Null2EmptyTrim(obj[12]);
			
			

			tempList.add(prof);
		}
		}
		
		searchRsList=tempList;
	}
	
	@Override
	protected void dealWithTheListSpecially(List<Object> list) {
	List<Object> tempList=new ArrayList<Object>();
	if(list!=null&&list.size()>0){
		try {
	
			Iterator iterator=list.iterator();
			while(iterator.hasNext()){
				ProfitDetail prof=new ProfitDetail();
					Object[] obj=(Object[]) iterator.next();
					prof.setAgentName(Constance.Null2EmptyTrim(obj[0]));
					prof.setMchtCd(Constance.Null2EmptyTrim(obj[1]));
					prof.setMchtName(Constance.Null2EmptyTrim(obj[2]));
					String cardClass=Constance.Null2EmptyTrim(obj[3]);
					String prodCd= Constance.Null2EmptyTrim(obj[4]);
					BigDecimal amt= new BigDecimal(Constance.null2Amt(obj[5]));
					BigDecimal feeffd= new BigDecimal(Constance.null2Amt(obj[6]));//封顶值
					BigDecimal merfee= new BigDecimal(Constance.null2Amt(obj[7]));//封顶值
					prof.setCardClass(cardClass);
					prof.setProdCd(prodCd);
					prof.setSAmt(amt);
					BigDecimal restMerfee=getMerfee(amt,merfee,feeffd,cardClass,prodCd);
					prof.setMerfee(restMerfee);
					prof.setTransDate(Constance.Null2EmptyTrim(obj[8]));
					//prof.setPriAcctNo(Constance.Null2EmptyTrim(obj[9]));
					prof.setPriAcctNo(Utils.dealCardNo(Constance.Null2EmptyTrim(obj[9])));
					prof.setKeyRsp(Constance.Null2EmptyTrim(obj[10]));
					prof.setTermId(Constance.Null2EmptyTrim(obj[11]));
					prof.setStlmDate(Constance.Null2EmptyTrim(obj[12]));
					tempList.add(prof);
					
			}
			
			
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		}
		
		searchRsList=tempList;
	}

	
	public BigDecimal getMerfee(BigDecimal amt,BigDecimal merfee,BigDecimal feeffd,String cardClass,String prodCd ){
		int r=merfee.compareTo(BigDecimal.ZERO);//费率是否等于0
		int deal=merfee.add(feeffd).compareTo(BigDecimal.ZERO);//是否封顶消费撤销
		int  repeal=merfee.compareTo(feeffd);//是否封顶消费
		BigDecimal profitSettleRate=BigDecimal.ZERO;
		BigDecimal  profitFee =BigDecimal.ZERO;
		BigDecimal  restMerfee =BigDecimal.ZERO;
		//获取该条交易对应代理商费率表对应的费率
		if(profitRuleMap.size()>0){//没有设置费率
			if("消费".equals(prodCd)){
				if(r<=0){
					return BigDecimal.ZERO;
				}else{
					if("借记卡".equals(cardClass)){
						if(repeal==0){
							 profitSettleRate= profitRuleMap.get("0199");
						}else{
							profitFee= profitRuleMap.get("0100");
						}
					}else if("云闪付借记卡".equals(cardClass)){
						profitFee= profitRuleMap.get("0500");
					}else if("云闪付贷记卡".equals(cardClass)){
						profitFee= profitRuleMap.get("0501");
					}else if(cardClass.contains("银联") && cardClass.contains("非日常")){
						profitFee= profitRuleMap.get("0600");
					}else if(cardClass.contains("银联") && cardClass.contains("日常")){
						profitFee= profitRuleMap.get("0700");
					}else if(cardClass.contains("银联") && cardClass.contains("非优惠")){
						profitFee= profitRuleMap.get("0600");
					}else if(cardClass.contains("银联") && cardClass.contains("优惠")){
						profitFee= profitRuleMap.get("0700");
					}else if(cardClass.contains("支付宝") || cardClass.contains("微信")){
						profitFee= profitRuleMap.get("0800");
					}else{
						profitFee= profitRuleMap.get("0101");
					}
				}
			}else if (prodCd.contains("撤销")||prodCd.contains("退货")){
				if(r>=0){
					return BigDecimal.ZERO;
				}else{
					if("借记卡".equals(cardClass)){
						if(deal==0){
							 profitSettleRate= profitRuleMap.get("0199").multiply(new BigDecimal(-1));
						}else{
							profitFee= profitRuleMap.get("0100");
						}
					}else if("云闪付借记卡".equals(cardClass)){
						profitFee= profitRuleMap.get("0500");
					}else if("云闪付贷记卡".equals(cardClass)){
						profitFee= profitRuleMap.get("0501");
					}else if(cardClass.contains("银联") && cardClass.contains("非日常")){
						profitFee= profitRuleMap.get("0600");
					}else if(cardClass.contains("银联") && cardClass.contains("日常")){
						profitFee= profitRuleMap.get("0700");
					}else if(cardClass.contains("银联") && cardClass.contains("非优惠")){
						profitFee= profitRuleMap.get("0600");
					}else if(cardClass.contains("银联") && cardClass.contains("优惠")){
						profitFee= profitRuleMap.get("0700");
					}else if(cardClass.contains("支付宝") || cardClass.contains("微信")){
						profitFee= profitRuleMap.get("0800");
					}else{
						profitFee= profitRuleMap.get("0101");
					}
				}
			}else{
				if("借记卡".equals(cardClass)){
					profitFee= profitRuleMap.get("0400");
				}else if("云闪付借记卡".equals(cardClass)){
					profitFee= profitRuleMap.get("0500");
				}else if("云闪付贷记卡".equals(cardClass)){
					profitFee= profitRuleMap.get("0501");
				}else if(cardClass.contains("银联") && cardClass.contains("非日常")){
					profitFee= profitRuleMap.get("0600");
				}else if(cardClass.contains("银联") && cardClass.contains("日常")){
					profitFee= profitRuleMap.get("0700");
				}else if(cardClass.contains("银联") && cardClass.contains("非优惠")){
					profitFee= profitRuleMap.get("0600");
				}else if(cardClass.contains("银联") && cardClass.contains("优惠")){
					profitFee= profitRuleMap.get("0700");
				}else if(cardClass.contains("支付宝") || cardClass.contains("微信")){
					profitFee= profitRuleMap.get("0800");
				}else{
					profitFee= profitRuleMap.get("0401");
				}
			}
		}else{
			profitFee=new BigDecimal(0.006);
		}
		
		
		if(profitSettleRate.compareTo(BigDecimal.ZERO)==0){//判断是否封顶
			profitSettleRate =AmtUtil.roundBigDecimal(amt.multiply(profitFee).doubleValue(), 2);
		}
		restMerfee=merfee.subtract(profitSettleRate);
		return restMerfee;
		
	}
	
	@Override
	protected String getInitPageSize() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected BaseSearchCondition getSearchConditionFromSession() {
		// TODO Auto-generated method stub
		return (BaseSearchCondition) getSession().getAttribute(SEARCH_SESSION_PROFIT_DASUM_QUERY);
	}

	@Override
	protected BaseSearchCondition getSearchConditionFromSubClass()
			throws Exception {
		// TODO Auto-generated method stub
		return searchCondition;
	}

	@Override
	protected void setSearchConditionToSubClass(
			BaseSearchCondition searchCondition) throws Exception {
		// TODO Auto-generated method stub
		this.setSearchConditionToSubClass(searchCondition);
	}

	@Override
	protected void setSearchToConditionSession(
			BaseSearchCondition searchCondition) {
		// TODO Auto-generated method stub
		getSession().setAttribute(SEARCH_SESSION_PROFIT_DASUM_QUERY, searchCondition);
	}


	public YsbProfitDetailQuerySearchCondition getSearchCondition() {
		return searchCondition;
	}


	public void setSearchCondition(YsbProfitDetailQuerySearchCondition searchCondition) {
		this.searchCondition = searchCondition;
	}


	public InputStream getExcelFile() {
		return excelFile;
	}


	public void setExcelFile(InputStream excelFile) {
		this.excelFile = excelFile;
	}
	public String getExcelName() {
		return excelName;
	}

	public void setExcelName(String excelName) {
		this.excelName = excelName;
	}


	public Map getProfitRuleMap() {
		return profitRuleMap;
	}


	public void setProfitRuleMap(Map profitRuleMap) {
		this.profitRuleMap = profitRuleMap;
	}

	public String getAccountNo() {
		return accountNo;
	}

	public void setAccountNo(String accountNo) {
		this.accountNo = accountNo;
	}
	

}
